package net.documentshare.utils;

import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

import net.documentshare.i.ICommonBeanAware;
import net.simpleframework.ado.DataObjectManagerUtils;
import net.simpleframework.ado.db.ITableEntityManager;
import net.simpleframework.ado.db.event.TableEntityAdapter;
import net.simpleframework.content.ContentUtils;
import net.simpleframework.core.IApplicationModule;
import net.simpleframework.core.id.ID;
import net.simpleframework.core.id.LongID;
import net.simpleframework.my.file.component.fileselect.FileSelectUtils;
import net.simpleframework.my.space.MySpaceUtils;
import net.simpleframework.my.space.SapceLogBean;
import net.simpleframework.organization.IUser;
import net.simpleframework.organization.OrgUtils;
import net.simpleframework.organization.account.AbstractAccountRule;
import net.simpleframework.organization.account.AccountContext;
import net.simpleframework.organization.account.AccountLog;
import net.simpleframework.organization.account.AccountSession;
import net.simpleframework.organization.account.IAccount;
import net.simpleframework.organization.impl.User;
import net.simpleframework.util.AlgorithmUtils;
import net.simpleframework.util.ConvertUtils;
import net.simpleframework.util.DateUtils;
import net.simpleframework.util.HTMLUtils;
import net.simpleframework.util.HTTPUtils;
import net.simpleframework.util.ImageUtils;
import net.simpleframework.util.StringUtils;
import net.simpleframework.web.EFunctionModule;
import net.simpleframework.web.IWebApplicationModule;
import net.simpleframework.web.WebUtils;
import net.simpleframework.web.page.AbstractUrlForward;
import net.simpleframework.web.page.PageRequestResponse;
import net.simpleframework.web.page.component.ComponentParameter;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public final class ItSiteUtil {

	public static String getSQLNullExpr(final Class<?> type, final String column) {
		final StringBuilder sb = new StringBuilder();
		sb.append(column);
		if (Number.class.isAssignableFrom(type)) {
			sb.append(" = 0");
		} else {
			sb.append(" is null");
		}
		return sb.toString();
	}

	public static ITableEntityManager getTableEntityManager(final IApplicationModule applicationModule, final Class<?> beanClazz) {
		return DataObjectManagerUtils.getTableEntityManager(applicationModule, beanClazz);
	}

	public static ITableEntityManager getTableEntityManager(final IApplicationModule applicationModule) {
		return DataObjectManagerUtils.getTableEntityManager(applicationModule);
	}

	public static boolean isManage(final PageRequestResponse requestResponse, final IWebApplicationModule module) {
		try {
			if (IWebApplicationModule.Utils.isManager(requestResponse, module)) {
				return true;
			}
		} catch (final Exception e) {
		}
		return false;
	}

	public static boolean isManageOrSelf(final PageRequestResponse requestResponse, final IWebApplicationModule module, final Object userId) {
		try {
			if (isManage(requestResponse, module)) {
				return true;
			}
			if (ItSiteUtil.getLoginUser(requestResponse).getId().equals(userId)) {
				return true;
			}
		} catch (Exception e) {
		}
		return false;
	}

	/**
	 * 区分大小写
	 */
	public static String replaceString(String source, String oldstring, String newstring, final boolean ignoreCase) {
		if (ignoreCase)
			return source.replaceAll(oldstring, newstring);//大小写敏感
		else
			return source.replaceAll("(?i)" + oldstring, newstring); //大小写不敏感 
	}

	public static String markContent(final String mark, final String content) {
		if (!StringUtils.hasText(mark))
			return content;
		return replaceString(content, mark, "<span style='color:red;'>" + mark + "</span>", false);
	}

	/**
	 * 格式化URL
	 * @return
	 */
	public static String formatUrl(final String url) {
		if (StringUtils.hasText(url)) {
			if (url.startsWith("http")) {
				return url;
			}
			return "http://" + url;
		}
		return "#";
	}

	/**
	 * 用户是否登入
	 * @return
	 */
	public static boolean isLogin(final PageRequestResponse requestResponse) {
		final IAccount login = AccountSession.getLogin(requestResponse.getSession());
		if (login == null) {
			return false;
		}
		return true;
	}

	/**
	 * 根据用户ID获得用户对象
	 * @param userId
	 * @return
	 */
	public static IUser getUserById(final Object userId) {
		return OrgUtils.um().queryForObjectById(userId);
	}

	/**
	 * 根据用户ID获得用户账号
	 * @param userId
	 * @return
	 */
	public static IAccount getAccountById(final Object userId) {
		return OrgUtils.am().queryForObjectById(userId);
	}

	/**
	 * 获得登入的用户
	 * @param requestResponse
	 * @return
	 */
	public static IUser getLoginUser(final PageRequestResponse requestResponse) {
		final IAccount account = AccountSession.getLogin(requestResponse.getSession());
		if (account == null) {
			final User u = new User();
			u.setId(new LongID(Long.MIN_VALUE));
			return u;
		}
		return account.user();
	}

	public static IAccount getLoginAccount(final PageRequestResponse requestResponse) {
		return AccountSession.getLogin(requestResponse.getSession());
	}

	/**
	 * 把图片格式转成可显示的标签
	 * @param compParameter
	 * @param content
	 * @return
	 */
	public static String doDownloadContent(final ComponentParameter compParameter, final String content) {
		final Document doc = Jsoup.parse(content);
		final Elements atts = doc.select("a[href^=" + FileSelectUtils.DOWNLOAD_FLAG + "]");
		if (atts.isEmpty()) {
			return content;
		}
		for (int i = 0; i < atts.size(); i++) {
			final Element att = atts.get(i);
			String dl = att.attr("href").substring(FileSelectUtils.DOWNLOAD_FLAG.length());
			att.removeAttr("href");
			final int p = dl.indexOf("?");
			final Map<String, Object> params = WebUtils.toQueryParams(dl.substring(p + 1));
			final String dl_points = compParameter.getRequestParameter("dl_points");
			if (StringUtils.hasText(dl_points)) {
				params.put("points", 1);
				params.put("posttext", 0);
			}
			final String nDL = AlgorithmUtils.base64Encode((dl.substring(0, p + 1) + WebUtils.toQueryString(params)).getBytes());
			att.attr("onclick", "$Actions['__my_folderfile_ajax_download']('dl=" + nDL + "');");
			if (true) {
				dl = compParameter.wrapContextPath(dl);
				try {
					final URL url = new URL(AbstractUrlForward.getLocalhostUrl(compParameter.request) + dl);
					if (ImageUtils.isImage(url)) {
						final Element img = doc.createElement("img");
						img.attr("src", WebUtils.addParameters(dl, "loc=true")).attr("style",
								"padding: 1px; border: 1px solid #999; max-width: 600px;");
						att.replaceWith(img);
					}
				} catch (final Exception e) {
				}
			}
		}
		return doc.body().html();
	}

	public static final long period = 60 * 60 * 24;// 默认隔一天清理一次
	public static final long weekperiod = 60 * 60 * 24 * 7;// 默认隔一天清理一次
	public static final String yyyyMMdd_HHmm = "yyyy-MM-dd HH:mm";
	public static final String yyyyMMdd = "yyyy-MM-dd";
	public static final String yyyyMMdd_HH = "yyyy-MM-dd HH";

	/**
	 * 当前时间到凌晨0点的时间间隔
	 * @return
	 */
	public static long get0Time() {
		final Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		cal.add(Calendar.DATE, 1);
		return (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
	}

	/**
	 * 获得周一的凌晨
	 * @return
	 */
	public static long getWeekTime() {
		final Calendar cal = Calendar.getInstance();
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		cal.set(Calendar.DAY_OF_WEEK, cal.getActualMaximum(Calendar.DAY_OF_WEEK));
		cal.add(Calendar.DATE, 2);
		return (cal.getTimeInMillis() - new Date().getTime()) / 1000;
	}

	public static String getHtmlEditorToolbar(final PageRequestResponse requestResponse, final String bean, final String content) {
		final StringBuilder sb = new StringBuilder();
		sb.append("<a class=\"simple_btn simple_btn_left\" ");
		sb.append("onclick=\"$Actions['fileUploadWindowAct']('refId=" + content + "');\">#(TopicPagerUtils.0)</a>");
		sb.append("<a class=\"simple_btn simple_btn_right\" ");
		sb.append("onclick=\"$Actions['__").append(bean);
		sb.append("_syntaxHighlighter'].editor();\">#(TopicPagerUtils.4)</a>");
		return sb.toString();
	}

	/**
	 * 当前点击的是哪个菜单
	 * @return
	 */
	public static String witchMenu(final PageRequestResponse requestResponse) {
		final String url = HTTPUtils.getRequestURI(requestResponse.request);
		final String h = requestResponse.getContextPath();
		if (url != null) {
			if (url.startsWith(h + "/news")) {
				return "资讯";
			} else if (url.startsWith(h + "/docu_corpus")) {
				return "文辑";
			} else if (url.startsWith(h + "/docu")) {
				return "文档";
			} else if (url.startsWith(h + "/question")) {
				return "问答";
			} else if (url.startsWith(h + "/blog")) {
				return "博客";
			} else if (url.startsWith(h + "/bbs")) {
				return "论坛";
			}
		}
		return "首页";
	}

	/**
	* 显示项目的发布者和发布时间
	* @return
	*/
	public static String layoutTime(PageRequestResponse requestResponse, final ICommonBeanAware commonBean) {
		final StringBuilder sb = new StringBuilder();
		sb.append(ContentUtils.getAccountAware().wrapAccountHref(requestResponse, commonBean.getUserId()));
		sb.append(", ");
		sb.append("<span>").append(ConvertUtils.toDateString(commonBean.getModifyDate(), "yyyy-MM-dd HH")).append("</span>");
		return sb.toString();
	}

	/**
	 * 显示项目的发布者和发布时间
	 * @return
	 */
	public static String layoutTime(PageRequestResponse requestResponse, final ICommonBeanAware commonBean, final String dateFormat,
			final boolean isNew) {
		final StringBuilder sb = new StringBuilder();
		sb.append(ContentUtils.getAccountAware().wrapAccountHref(requestResponse, commonBean.getUserId()));
		sb.append(", ");
		if (dateFormat != null) {
			try {
				sb.append(ConvertUtils.toDateString(commonBean.getModifyDate(), dateFormat));
			} catch (final Exception ex) {
				sb.append(ex.getMessage());
			}
		} else {
			sb.append("<span title=\"" + ConvertUtils.toDateString(commonBean.getModifyDate()) + "\">")
					.append(DateUtils.getRelativeDate(commonBean.getModifyDate())).append("</span>");
		}
		if (isNew) {
			final Calendar cal = Calendar.getInstance();
			cal.add(Calendar.HOUR, -12);
			if (commonBean.getModifyDate().after(cal.getTime())) {
				sb.append("<span class=\"new_gif_image\" style=\"margin-left: 10px;\"></span>");
			}
		}
		return sb.toString();
	}

	/**
	 * 显示评论的用户和时间，8小时内的评论标新
	 * @return
	 */
	public static String layoutRemarkTime(PageRequestResponse requestResponse, final ICommonBeanAware commonBean) {
		final StringBuilder sb = new StringBuilder();
		final Date date = commonBean.getRemarkDate() == null ? commonBean.getModifyDate() : commonBean.getRemarkDate();
		sb.append("<span title=\"" + ConvertUtils.toDateString(date) + "\">").append(DateUtils.getRelativeDate(date)).append("</span>");
		sb.append(", ");
		final Object userId = commonBean.getRemarkUserId() == null || commonBean.getRemarkUserId().equals2(0) ? commonBean.getUserId() : commonBean
				.getRemarkUserId();
		sb.append("By ");
		sb.append(ContentUtils.getAccountAware().wrapAccountHref(requestResponse, userId));
		final Calendar cal = Calendar.getInstance();
		cal.add(Calendar.HOUR, -12);
		if (date.after(cal.getTime())) {
			sb.append("<span class=\"new_gif_image\" style=\"margin-left: 10px;\"></span>");
		}
		return sb.toString();
	}

	public static String layoutRemarkAndViewAndVote(final ICommonBeanAware commonBean) {
		final StringBuilder sb = new StringBuilder();
		sb.append("<span class=\"nnum\" title=\"" + commonBean.getRemarks() + "评论/" + commonBean.getViews() + "阅读\">");
		if (commonBean.isNewRemark()) {
			sb.append("<span class=\"nnum _red\">");
			sb.append(commonBean.getRemarks());
			sb.append("</span>");
		} else {
			sb.append(commonBean.getRemarks());
		}
		sb.append("评论/").append(commonBean.getViews()).append("阅读");
		sb.append("</span>");
		return sb.toString();
	}

	/**
	 * 显示阅读，评论次数
	 * @param commonBean
	 * @return
	 */
	public static String layoutRemarkAndView(final ICommonBeanAware commonBean, final boolean today) {
		final StringBuilder sb = new StringBuilder();
		sb.append("<span class=\"nnum\" title=\"" + commonBean.getRemarks() + "评论/" + (today ? commonBean.getTodayViews() : commonBean.getViews())
				+ "阅读\">");
		if (commonBean.isNewRemark()) {
			sb.append("<span class=\"nnum _red\">");
			sb.append(commonBean.getRemarks());
			sb.append("</span>");
		} else {
			sb.append(commonBean.getRemarks());
		}
		sb.append("/").append(today ? commonBean.getTodayViews() : commonBean.getViews());
		sb.append("</span>");
		return sb.toString();
	}

	/**
	 * 添加日志
	 * @param account
	 * @param content
	 */
	public static void addSpaceLog(final IAccount account, final String content, final EFunctionModule functionModule, final ID refId) {
		final ITableEntityManager log_mgr = MySpaceUtils.getTableEntityManager(SapceLogBean.class);
		final SapceLogBean sapceLog = new SapceLogBean();
		sapceLog.setUserId(account.getId());
		sapceLog.setCreateDate(new Date());
		sapceLog.setContent(content);
		sapceLog.setRefId(refId);
		sapceLog.setRefModule(functionModule);
		log_mgr.insert(sapceLog);
	}

	/**
	 * 
	 * @param content
	 * @param length
	 * @return
	 */
	public static String getShortString(final String content, final int length, final boolean more) {
		if (content.length() < length)
			return content;
		return content.substring(0, length) + (more ? "..." : "");
	}

	public static String getShortContent(final String content, final int length, final boolean newLine) {
		return HTMLUtils.truncateHtml(HTMLUtils.createHtmlDocument(content, false), length, newLine, true, true);
	}

	/**
	 * 交换积分
	 */
	public static void switchPoint(final PageRequestResponse requestResponse, final int sPoint, final Object userId, final ID id) {
		//交换积分
		final IAccount account = ItSiteUtil.getAccountById(ItSiteUtil.getLoginUser(requestResponse).getId());
		if (account != null) {
			account.setPoints(account.getPoints() - sPoint);
			OrgUtils.am().getEntityManager().updateTransaction(new Object[] { "points" }, account, new TableEntityAdapter() {
				public void afterUpdate(ITableEntityManager manager, Object[] objects) {
					final IAccount toaccount = ItSiteUtil.getAccountById(userId);
					toaccount.setPoints(toaccount.getPoints() + sPoint);
					//下载文档，扣除积分
					ItSiteUtil.addAccountLog(account.getId(), "下载文档", -sPoint, 0, id);
					AbstractAccountRule accountRule = (AbstractAccountRule) AccountContext.getAccountRule("docu_down1");
					accountRule.setPoints(-sPoint);
					AccountContext.update(account, accountRule, id, false);
					//下载别人的文档，别人增加积分
					ItSiteUtil.addAccountLog(toaccount.getId(), "下载文档", sPoint, 0, id);
					accountRule = (AbstractAccountRule) AccountContext.getAccountRule("docu_down2");
					accountRule.setPoints(sPoint);
					AccountContext.update(toaccount, accountRule, id, false);
					OrgUtils.am().update(new String[] { "points" }, toaccount);
				};
			});
		}
	}

	/**
	 * 更新账号日志
	 */
	public static void addAccountLog(final ID userId, final String eventId, final int point, final int exp, final ID logId) {
		final AccountLog log = new AccountLog();
		log.setAccountId(userId);
		log.setEventId(eventId);
		log.setCreateDate(new Date());
		log.setExp(exp);
		log.setPoints(point);
		log.setLogId(logId);
	}

	public static String buildVote(ICommonBeanAware beanAware, final String id) {
		final StringBuffer buf = new StringBuffer();
		buf.append("<span class='__vote voteUp' ");
		buf.append("param='voteValue=1&").append(id);
		buf.append("=").append(beanAware.getId()).append("'>").append("顶</span>");
		buf.append("<span class='voteValue' title='点击隐藏' id='voteValue' onclick=\"this.up('div').$toggle();\">").append(beanAware.getVotes())
				.append("</span>");
		buf.append("<span class='__vote voteDown' ");
		buf.append("param='voteValue=-1&").append(id);
		buf.append("=").append(beanAware.getId()).append("'>").append("踩</span>");
		return buf.toString();
	}
}
